FELIX-6759 - PROTOTYPE: use plurl for URL handler factory multiplexing - #552
FELIX-6759 - PROTOTYPE: use plurl for URL handler factory multiplexing#552paulrutter wants to merge 7 commits into
Conversation
Not for merge. This explores the suggestion in #433 (comment) that Felix and Equinox should share a cooperative way to manage the java.net.URL factory singletons. URLHandlers currently claims the JVM-wide URLStreamHandlerFactory by reflectively swapping a private static field on java.net.URL (SecureAction.swapStaticFieldIfNotClass). Getting a MethodHandles.Lookup trusted enough to do that is the only remaining reason the framework uses sun.misc.Unsafe, and it means the last framework to install itself wins the singleton, so two frameworks cannot coexist in one JVM without clobbering each other. Plurl installs a single cooperative router through the supported URL.setURLStreamHandlerFactory API and lets any number of parties register with it; each registered factory answers shouldHandle(Class) to claim the calling class. That maps onto what URLHandlers.getFrameworkFromContext() already does by hand, and it needs no Unsafe. - Vendors the 11 plurl sources from eclipse-osgi-technology/plurl (commit 6581777) into org.apache.felix.framework.plurl. The only change is the package rename; every license header and copyright notice is preserved verbatim. This mirrors eclipse-equinox/equinox#848, which vendored the same files into org.eclipse.equinox.plurl. - Adds PlurlURLHandlers, adapting URLHandlers to PlurlStreamHandlerFactory and PlurlContentHandlerFactory, with shouldHandle(Class) recognising this framework's bundle class loaders. UNRESOLVED LICENSING QUESTION: every vendored file declares "SPDX-License-Identifier: EPL-2.0" and "Copyright (c) 2025 IBM Corporation", while plurl's own LICENSE and pom.xml declare Apache-2.0. EPL-2.0 is Category B at the ASF and may not be included in an Apache source release, so this cannot be merged as it stands. See framework/src/main/java/org/apache/felix/framework/plurl/README.md. Verified on JDK 25: the framework compiles and its tests are unchanged (the same 8 pre-existing platform specific failures as before this commit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The pull_request trigger filters on the BASE branch, and only accepted master. A stacked pull request - one opened against another feature branch rather than master - therefore matched neither trigger and got no CI at all, which is what happened to PR #552. Accept feature/** and maintenance/** as a base as well, so stacked work is built before it is merged down. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI is red on purpose — Apache RAT rejects the vendored sourcesNow that stacked PRs get CI (the All 12 flagged files are the vendored plurl sources — the 11 This is the licensing question answering itself. The failure is being left in place deliberately. It could be silenced with a RAT exclusion for So the technical side is done and the remaining blocker is purely licensing:
@tjwatson — if the EPL headers are carried over from the original Equinox code rather than intended, correcting them upstream to match plurl's own Apache-2.0 LICENSE and pom would turn this red build green and unblock the approach for Felix and anyone else wanting to adopt the library. If they are intentionally EPL-2.0, then Felix needs one of the alternatives listed in the PR description instead. 🤖 Generated with Claude Code |
|
The intention when I moved the source to Somehow that was overlooked when setting up the source in https://github.com/eclipse-osgi-technology/plurl It should be a non-issue to get the headers updated. But what I ultimately wanted to do was have a release out of the osgi-technology project for plurl that would be used by both Equinox and Felix unchanged, in the original package there. |
Thanks for your quick reply! Let's first see if we can get consensus on the JDK 25 PR, then we can revisit this one. Would it be possible to get plurl released as a separate artifact, with the right headers, so we can use it without copying the code into Felix? Apart from that, does this PR make sense to you? |
Warning
Draft / prototype — not for merge. There is an unresolved licensing question below that blocks this as it stands.
Prototype exploring @tjwatson's suggestion in #433 (comment) that Felix and Equinox should share a cooperative mechanism for the
java.net.URLfactory singletons. Branches off, and targets, #433.The problem
URLHandlersclaims the JVM-wideURLStreamHandlerFactoryby reflectively swapping a private static field onjava.net.URL, viaSecureAction.swapStaticFieldIfNotClass. Obtaining aMethodHandles.Lookuptrusted enough to do that is the only remaining reason the framework usessun.misc.Unsafe— thestaticFieldOffset/getObjectsteal ofIMPL_LOOKUP. It also means whichever framework installs itself last wins the singleton, so Felix and Equinox cannot coexist in one JVM without clobbering each other.To be clear about urgency: this is not a JDK 25 blocker. That
Unsafeblock is guarded bycatch (Throwable)and falls back toAccessibleObject.setAccessible, so on JDK 25 it only produces the familiar warning. This is about JDK 26+ and about framework interop.What this does
6581777) intoorg.apache.felix.framework.plurl. The only change is the package rename; every license header and copyright notice is preserved verbatim. This mirrors what Equinox did in Plurl API for managing Java singleton factories in URL eclipse-equinox/equinox#848.PlurlURLHandlers, adaptingURLHandlerstoPlurlStreamHandlerFactory/PlurlContentHandlerFactory. Plurl installs one cooperative router through the supportedURL.setURLStreamHandlerFactoryAPI and routes by asking each registered factoryshouldHandle(Class)— which maps directly onto whatURLHandlers.getFrameworkFromContext()already does by hand, and needs noUnsafe.Verified on JDK 25: the framework compiles and its test results are unchanged.
Every vendored source file declares:
but plurl's own
LICENSEfile and itspom.xmlboth declare Apache-2.0. (ItsNOTICEalso still refers to "slf4j-osgi", which looks like a copy-paste leftover.)This matters because of where it is being copied to. EPL-2.0 is Category B at the ASF and must not be included in an Apache source release. Equinox was free to vendor these files because Eclipse projects are EPL-2.0 natively; Felix is not.
Given the repo's LICENSE and pom say Apache-2.0, my guess is the EPL headers are carried over from the original Equinox code rather than intended. Could you confirm the intended license and, if it is Apache-2.0, correct the source headers upstream? That would unblock the vendoring approach for Felix and anyone else.
If the headers are intentionally EPL-2.0, then Felix cannot vendor the sources and the options become:
cc @stbischof @laeubi @mattrpav
🤖 Generated with Claude Code